home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 376-400 / disk_376 / toollibrary / src / simplemenu.c < prev    next >
Text File  |  1992-05-06  |  11KB  |  393 lines

  1.  /********************************************************************/
  2.  /****                                                            ****/
  3.  /****                                                            ****/
  4.  /****    Program          : SimpleMenu.c                         ****/
  5.  /****                                                            ****/
  6.  /****    Version          :    03.71                             ****/
  7.  /****                                                            ****/
  8.  /****    Erstversion      : 14.03.1990                           ****/
  9.  /****                                                            ****/
  10.  /****    Letzte Änderung  : 08.08.1990                           ****/
  11.  /****                                                            ****/
  12.  /****    Compiliert mit   : siehe MAKEFILE                       ****/
  13.  /****                                                            ****/
  14.  /****    Gelinkt mit      : siehe MAKEFILE                       ****/
  15.  /****                                                            ****/
  16.  /********************************************************************/
  17.  /****                                                            ****/
  18.  /****                                                            ****/
  19.  /****               Copyright by Rüdiger Dreier                  ****/
  20.  /****                                                            ****/
  21.  /****                                                            ****/
  22.  /********************************************************************/
  23.  
  24.  #include <exec/types.h>
  25.  #include <stdio.h>
  26.  #include <intuition/intuition.h>
  27.  #include <intuition/intuitionbase.h>
  28.  #include <exec/types.h>
  29.  #include <exec/memory.h>
  30.  #include <proto/dos.h>
  31.  #include <proto/exec.h>
  32.  #include <proto/intuition.h>
  33.  #include <stdio.h>
  34.  #include <string.h>
  35.  
  36.  /* Gibt Zeiger auf das letzte definierte Menu zurück */
  37.  struct Menu * __asm LastMenu(register __a0 struct Menu *menu)
  38.   {
  39.    if(menu==NULL)return(NULL); /* Kein Menu definiert */
  40.    
  41.    while(menu->NextMenu!=NULL)
  42.     {
  43.      menu=menu->NextMenu;
  44.     }
  45.    return(menu);
  46.   }
  47.  
  48.  
  49.  /* Gibt Zeiger auf das letzte definierte Item zurück */
  50.  struct MenuItem * __asm LastItem(register __a0 struct Menu *menu)
  51.   {
  52.    struct MenuItem *item;
  53.    if(menu==NULL)return(NULL); /* Kein Menu definiert  */
  54.    
  55.    menu=LastMenu(menu);        /* Der letzte MenuPunkt */
  56.    
  57.    item=menu->FirstItem;
  58.    if(item==NULL)return(NULL); /* Kein Item */
  59.    
  60.    
  61.    while(item->NextItem!=NULL)
  62.     {
  63.      item=item->NextItem;
  64.     }
  65.    return(item);               /* Das letzte Item      */
  66.   }
  67.  
  68.  
  69.  /* Gibt Zeiger auf das letzte definierte SubItem zurück */
  70.  struct MenuItem * __asm LastSub(register __a0 struct Menu *menu)
  71.   {
  72.    struct MenuItem *item,*sub;
  73.    if(menu==NULL)return(NULL); /* Kein Menu definiert   */
  74.    
  75.    item=LastItem(menu);        /* Der letzte ItemPunkt  */
  76.    
  77.    sub=item->SubItem;
  78.    if(sub==NULL)return(NULL); /* Kein SubItem */
  79.    
  80.    while(sub->NextItem!=NULL)
  81.     {
  82.      sub=sub->NextItem;
  83.     }
  84.    return(sub);                /* Das letzte SubItem    */
  85.   }
  86.  
  87.  
  88.  /* Hängt ein Menu an */ 
  89.  struct Menu * __asm AddMenu(register __a0 struct Menu *menu,
  90.                              register __a1 char *Titel,
  91.                              register __d0 USHORT Flags)
  92.   {
  93.    struct Menu *newmenu,*lastmenu;
  94.    struct IntuiText Hilfe;
  95.    
  96.    newmenu=AllocMem(sizeof(struct Menu),MEMF_CLEAR|MEMF_PUBLIC);
  97.    if(newmenu==NULL)return(NULL); /* Kein Speicher für Menu */
  98.    
  99.    /* Den Speicher hab ich jetzt. Jetzt kann die Struktur */
  100.    /* gefüllt werden.                                     */
  101.    
  102.    lastmenu=LastMenu(menu);
  103.    if(lastmenu!=NULL)
  104.     {
  105.      /* Wenn schon ein Menu vorhanden, sonst 0 */
  106.      newmenu->LeftEdge=lastmenu->LeftEdge+lastmenu->Width;
  107.      lastmenu->NextMenu=newmenu;
  108.     }
  109.    newmenu->MenuName=Titel;
  110.    newmenu->Flags=Flags;
  111.    Hilfe.ITextFont=0;
  112.    Hilfe.IText=Titel;
  113.    newmenu->Width=(IntuiTextLength(&Hilfe)+8);
  114.    return(newmenu);  /* Ist das erste Menu    */
  115.   }
  116.  
  117.  
  118.  /* Hängt ein Item an */ 
  119.  struct Item * __asm AddItem(register __a0 struct Menu *menu,
  120.                              register __a1 char *Titel,
  121.                              register __d0 USHORT Flags,
  122.                              register __d1 char HotKey)
  123.   {
  124.    struct Menu *lastmenu;
  125.    struct MenuItem *newitem,*lastitem;
  126.    
  127.    newitem=GetItem(menu,Titel,Flags,HotKey); /* Speicher für Item holen */
  128.    if(!newitem)return(NULL);
  129.    
  130.    lastmenu=LastMenu(menu);
  131.    lastitem=LastItem(menu);
  132.    
  133.    if(lastitem==NULL) /* Item in Liste einfügen */
  134.     {
  135.      lastmenu->FirstItem=newitem;
  136.     }
  137.    else
  138.     {
  139.      lastitem->NextItem=newitem;
  140.     }
  141.    return(newitem);
  142.   }
  143.  
  144.  
  145.  /* Hängt ein SubItem an */ 
  146.  struct Item * __asm AddSub(register __a0 struct Menu *menu,
  147.                             register __a1 char *Titel,
  148.                             register __d0 USHORT Flags,
  149.                             register __d1 char HotKey)
  150.   {
  151.    struct MenuItem *newsub,*lastitem,*lastsub;
  152.    
  153.    lastitem=LastItem(menu);
  154.    lastsub =LastSub(menu);
  155.    if(lastitem==NULL)return(NULL); /* Ohne Item kein SubItem */
  156.    
  157.    newsub=GetItem(menu,Titel,Flags,HotKey); /* Speicher für Item holen */
  158.    if(newsub==NULL)return(NULL); /* Kein Speicher für Item */
  159.    
  160.    if(lastsub==NULL) /* Item in Liste einfügen */
  161.     {
  162.      lastitem->SubItem=newsub;
  163.     }
  164.    else
  165.     {
  166.      lastsub->NextItem=newsub;
  167.     }
  168.    return(newsub);
  169.   }
  170.  
  171.  
  172.  /* Holt und füllt dem Speicher für ein Item oder SubItem */
  173.  struct MenuItem * __asm GetItem(register __a0 struct Menu *menu,
  174.                                  register __a1 char *Titel,
  175.                                  register __d0 USHORT Flags,
  176.                                  register __d1 char HotKey)
  177.   {
  178.    struct IntuiText *newtext;
  179.    struct MenuItem *newitem;
  180.    SHORT addwidth=0;
  181.    
  182.    if(menu==NULL)return(NULL);  /* Ohne Menu kein Item             */
  183.    if(Titel==NULL)return(NULL); /* Ohne Text oder Grafik kein Item */
  184.    
  185.    newitem=AllocMem(sizeof(struct MenuItem),MEMF_CLEAR|MEMF_PUBLIC);
  186.    if(newitem==NULL)return(NULL); /* Kein Speicher für Menu */
  187.    if(Titel&&(Flags&ITEMTEXT))
  188.     {
  189.      /* Nur, wenn keine Grafik */
  190.      newtext=AllocMem(sizeof(struct IntuiText),MEMF_CLEAR|MEMF_PUBLIC);
  191.      if(newtext==NULL)
  192.       {
  193.        /* Kein Speicher für IntuiText */
  194.        FreeMem(newitem,sizeof(struct MenuItem));
  195.        return(NULL);
  196.       }
  197.      /* Den Speicher hab ich jetzt. Jetzt können die Strukturen */
  198.      /* gefüllt werden.                                         */
  199.      if(menu->FirstItem)
  200.       {
  201.        newtext->FrontPen=((struct IntuiText *)menu->FirstItem->ItemFill)->FrontPen;
  202.        newtext->BackPen =((struct IntuiText *)menu->FirstItem->ItemFill)->BackPen;
  203.        newtext->DrawMode=((struct IntuiText *)menu->FirstItem->ItemFill)->DrawMode;
  204.       }
  205.      else
  206.       {
  207.        newtext->FrontPen=2;   /* BackPen = 0 */
  208.        newtext->DrawMode=JAM1;
  209.       }
  210.      newtext->IText=Titel;
  211.      newtext->LeftEdge=3;
  212.     }
  213.    
  214.    if(Flags&COMMSEQ)addwidth=40; /* reicht für Standart-Symbol */
  215.    if(Flags&ITEMTEXT)
  216.     {
  217.      newitem->ItemFill=(APTR)newtext;
  218.      newitem->Width=IntuiTextLength(newtext)+addwidth+7;
  219.     }
  220.    else
  221.     {
  222.      newitem->ItemFill=(APTR)Titel;
  223.      newitem->Width=addwidth+((struct Image *)Titel)->Width+((struct Image *)Titel)->LeftEdge;
  224.      newitem->Height=((struct Image *)Titel)->Height+((struct Image *)Titel)->TopEdge;
  225.     }
  226.    newitem->Flags=Flags;
  227.    newitem->Command=HotKey;
  228.    
  229.    return(newitem);
  230.   }
  231.  
  232.  
  233.  /* Gibt den ganzen Speicher wieder frei */
  234.  VOID __asm ClearMenu(register __a0 struct Menu *menu)
  235.   {
  236.    struct MenuItem *item,*sub;
  237.    if(menu==NULL)return;
  238.    
  239.    while(menu)
  240.     {
  241.      item=menu->FirstItem;
  242.      while(item)
  243.       {
  244.        sub=item->SubItem;
  245.        while(sub)
  246.         {
  247.          sub=FreeItem(sub);
  248.         }
  249.        item=FreeItem(item);
  250.       }
  251.      menu=FreeMenu(menu);
  252.     }
  253.   }
  254.  
  255.  
  256.  struct MenuItem * __asm FreeItem(register __a0 struct MenuItem *item)
  257.   {
  258.    struct MenuItem *next=item->NextItem;
  259.    if((item->Flags&ITEMTEXT))FreeMem(item->ItemFill,sizeof(struct IntuiText));
  260.    FreeMem(item,sizeof(struct MenuItem));
  261.    return(next);
  262.   }
  263.  
  264.  
  265.  struct Menu * __asm FreeMenu(register __a0 struct Menu *menu)
  266.   {
  267.    struct Menu *next=menu->NextMenu;
  268.    FreeMem(menu,sizeof(struct Menu));
  269.    return(next);
  270.   }
  271.  
  272.  
  273.  /* Gleicht die Höhe der Items an, je nach Font im RastPort */
  274.  VOID __asm NewSetMenuStrip(register __a1 struct Window *Window,
  275.                             register __a0 struct Menu *menu)
  276.   {
  277.    struct MenuItem *item,*sub;
  278.    struct Menu *MENU;
  279.    SHORT hoehe,topedges,topedgei,maxwidthi,maxwidths,diff,v;
  280.    
  281.    if(menu==NULL)return; /* Notausgang */
  282.    
  283.    MENU=menu;            /* Merken     */
  284.    hoehe=Window->RPort->TxHeight; /* Fonthöhe        */
  285.    v=Window->WScreen->Height-16;  /* Höhe des Screen */
  286.    
  287.    while(menu)
  288.     {
  289.      item=menu->FirstItem;
  290.      if(item)topedgei=item->TopEdge;
  291.      while(item)
  292.       {
  293.        sub=item->SubItem;
  294.        if(sub)topedges=5;
  295.        while(sub)
  296.         {
  297.          /* Subs einpassen */
  298.          sub->TopEdge=topedges;
  299.          if(sub->Height==NULL)
  300.           {
  301.            sub->Height=hoehe;
  302.            topedges+=hoehe;
  303.           }
  304.          else
  305.           {
  306.            topedges+=sub->Height;
  307.           }
  308.          sub=sub->NextItem;
  309.          if(!sub)
  310.           {
  311.            diff=v-topedges-topedgei;
  312.            /* Hier wird kontrolliert, ob die SubItems zu weit nach unten reichen */
  313.            /* Wenn dies der Fall ist, werden sie nach oben verschoben.           */
  314.            /* Es wird NICHT geprüft, ob sie dadurch zu weit nach oben reichen.   */
  315.            /* Der Vergleichswert von 240 gilt für eine Screen mit 256 Zeichen.   */
  316.            if(diff<0)
  317.             {
  318.              sub=item->SubItem;
  319.              while(sub)
  320.               {
  321.                sub->TopEdge+=diff;
  322.                sub=sub->NextItem;
  323.               }
  324.             }
  325.           }
  326.         }
  327.        
  328.        /* Items einpassen */
  329.        item->TopEdge=topedgei;
  330.        if(item->Height==NULL)
  331.         {
  332.          item->Height=hoehe;
  333.          topedgei+=hoehe;
  334.         }
  335.        else
  336.         {
  337.          topedgei+=item->Height;
  338.         }
  339.        item=item->NextItem;
  340.       }
  341.      menu=menu->NextMenu;
  342.     }
  343.    
  344.    menu=MENU;
  345.    while(menu)
  346.     {
  347.      maxwidthi=menu->Width;
  348.      item=menu->FirstItem;
  349.      while(item)
  350.       {
  351.        /* 1. Pass: maxwidth feststellen */
  352.        maxwidths=0;
  353.        sub=item->SubItem;
  354.        while(sub)
  355.         {
  356.          /* 1. Pass: maxwidth feststellen */
  357.          maxwidths=max(sub->Width,maxwidths);
  358.          sub=sub->NextItem;
  359.         }
  360.        sub=item->SubItem;
  361.        while(sub)
  362.         {
  363.          /* 2. Pass: maxwidth einsetzen */
  364.          sub->Width=maxwidths;
  365.          sub=sub->NextItem;
  366.         }
  367.        
  368.        /* Items einpassen */
  369.        maxwidthi=max(item->Width,maxwidthi);
  370.        item=item->NextItem;
  371.       }
  372.      
  373.      item=menu->FirstItem;
  374.      while(item)
  375.       {
  376.        /* 2. Pass: maxwidth einsetzen */
  377.        item->Width=maxwidthi;
  378.        sub=item->SubItem;
  379.        while(sub)
  380.         {
  381.           /* In der Hoffnung, daß jedes Item mind. */
  382.           /* 5 Pixel breit ist....                 */
  383.          sub->LeftEdge=max(maxwidthi/2,maxwidthi-sub->Width/2);
  384.          sub=sub->NextItem;
  385.         }
  386.        item=item->NextItem;
  387.       }
  388.      menu=menu->NextMenu;
  389.     }
  390.    SetMenuStrip(Window,MENU);
  391.   }
  392.  
  393.